
#include "heart_beat.h"

// 定义互斥锁，确保更新和检查心跳时间时不会产生竞态条件
extern pthread_mutex_t heartbeat_lock;

// 记录客户端信息的数组
extern struct client_info clients[10];

// 初始化客户端信息
void init_client_info()
{
	for (int i = 0; i < 10; i++)
	{
		clients[i].fd = -1;
		clients[i].last_heartbeat = 0;
	}
}

// 更新客户端心跳时间
void update_client_heartbeat(int fd)
{
	// 加锁，防止竞态条件
	pthread_mutex_lock(&heartbeat_lock);
	for (int i = 0; i < 10; i++)
	{
		if (clients[i].fd == fd)
		{
			// 更新心跳时间
			clients[i].last_heartbeat = time(NULL);
			break;
		}
	}
	// 解锁
	pthread_mutex_unlock(&heartbeat_lock);
}

// 处理客户端消息，确保所有收到的数据都更新心跳时间
void handle_client_message(int listenfd, char *buf)
{
	if (strstr(buf, "\"type\":\"heartbeat\"") != NULL)
	{
		// 如果是心跳包，更新心跳时间
		update_client_heartbeat(listenfd);
	}
	else
	{
		// 无论什么数据，更新心跳时间
		update_client_heartbeat(listenfd);
	}
}

// 线程函数：定期发送心跳包并检查客户端超时
void *send_heartbeat(void *arg)
{
	char timeout_msg[1024] = {0};
	strcpy(timeout_msg, "{\"type\":\"timeout\",\"message\":\"您已超时，服务器将关闭连接。\"}"); // 发送给客户端JSON，已经超时结束!!!
	int epollfd = *(int *)arg;
	int ret = 0;

	while (1)
	{
		sleep(1); // 每秒检测一次
		time_t now = time(NULL);

		// 加锁，防止竞态条件
		pthread_mutex_lock(&heartbeat_lock);
		for (int i = 0; i < 10; i++)
		{
			if (clients[i].fd != -1 && now - clients[i].last_heartbeat > 60)
			{
				printf("客户端%d超时，关闭连接\n", clients[i].fd);

				// 发送超时消息给客户端
				ret = send(clients[i].fd, timeout_msg, strlen(timeout_msg), 0);
				if (ret == -1)
				{
					perror("send");
				}

				// 关闭连接
				epoll_ctl(epollfd, EPOLL_CTL_DEL, clients[i].fd, NULL);
				close(clients[i].fd);
				remove_client(clients[i].fd);
			}
		}
		// 解锁
		pthread_mutex_unlock(&heartbeat_lock);
	}
	return NULL;
}

// 移除客户端信息
void remove_client(int fd)
{
	for (int i = 0; i < 10; i++)
	{
		if (clients[i].fd == fd)
		{
			clients[i].fd = -1;
			break;
		}
	}
}
